<template>
  <div class="container">
    <div class="video-wrap">
      <div class="video" ref="videoList" :style="videoStyle">
        <div class="player-wrap" v-for="ind in videoNum" :key="ind" @click="videoPlayerClick(ind - 1)">
          <NstdVideoPlayer
            playType="realVideo"
            :lbFlag="lbFlag"
            :videoList="videoList"
            :videoConf="videoList[ind - 1]"
            v-if="videoList.length > 0 && videoList[ind - 1] && videoList[ind - 1].parentCode"
          ></NstdVideoPlayer>
          <div
            class="mark"
            :class="deviceIndex === ind - 1 ? 'active' : ''"
            v-if="videoList[ind - 1]"
            @click="videoPlayerClick(ind - 1)"
          ></div>
        </div>
      </div>
      <div class="video-opt">
        <template v-for="(itm, ind) in videoOptList">
          <el-popover placement="top" width="100" trigger="hover" v-if="itm.value === 'lunbo'">
            <div style="display: flex">
              <el-input-number
                size="mini"
                placeholder="轮播间隔（s）"
                v-model="lbTime"
                :min="0"
                controls-position="right"
                style="width: 100%"
              />
              <div style="color: #fff; align-self: center; margin-left: 5px">秒</div>
            </div>
            <div slot="reference" class="opreat" @click="videoOptClick(itm)" :key="itm + ind">
              <img :src="itm.src" alt="" />
              <span>{{ itm.name }}</span>
            </div>
          </el-popover>
          <div
            class="opreat"
            v-else-if="itm.type === 'opreat' && itm.value !== 'lunbo'"
            @click="videoOptClick(itm)"
            :key="itm + ind"
          >
            <img :src="itm.src" alt="" />
            <span>{{ itm.name }}</span>
          </div>
          <div class="devider" v-else :key="ind"></div>
        </template>
      </div>
    </div>
    <RobotControlDia
      v-if="[1, 2, 3].includes(currentDeviceInfo.mountPatroldeviceType)"
      :robot="currentDeviceInfo.mountPatroldeviceCode"
      :setShow="setShow"
      class="real-robot"
      @handleClose="handleClose"
    />
    <div v-else class="opt-wrap">
      <div class="dial-wrap">
        <div class="opt-left">
          <img
            :src="item.src"
            alt=""
            v-for="(item, index) in optList"
            :key="index"
            :style="item.style"
            @mouseup="controlClick(item, 'up')"
            @mousedown="controlClick(item, 'down')"
          />
          <div class="center-icon"></div>
        </div>
        <div class="opt-right">
          <span class="txt">速度调节:</span>
          <el-slider class="speed" v-model="speed" :marks="speedMarks"></el-slider>
        </div>
      </div>
      <div class="opt-btns">
        <img
          :src="item.src"
          alt=""
          v-for="(item, index) in btnsList"
          :key="index"
          class="btns"
          :title="item.title"
          @mouseup="controlClick(item, 'up')"
          @mousedown="controlClick(item, 'down')"
        />
      </div>
      <!-- <div class="voice-video">
        <div class="box" @click="voiceBtnClick">
          <img :src="voiceSrc" alt="" />
          <span class="txt">{{ voiceFlag ? '语音对讲' : '停止对讲' }}</span>
        </div>
        <el-popover placement="top" width="100" trigger="hover">
          <div style="display: flex">
            <el-input-number
              size="mini"
              placeholder="手动设定时长（min）"
              v-model="lxTime"
              :min="0"
              controls-position="right"
              style="width: 100%"
            />
            <div style="color: #fff; align-self: center; margin-left: 5px">分</div>
          </div>
          <div slot="reference" class="box" @click="videoBtnClick">
            <img :src="videoSrc" alt="" />
            <span class="txt">{{ videoFlag ? '启动录像' : '停止录像' }}</span>
          </div>
        </el-popover>
      </div> -->
      <!-- <div class="position-wrap">
        <span>预置位：</span>
        <el-select
          class="tree-type"
          v-model="presetPosition"
          placeholder="请选择"
          slot="head"
          size="mini"
          filterable
          clearable
        >
          <el-option
            v-for="(item, index) in positionList"
            :key="item.presetPosition + index"
            :label="item.presetName"
            :value="item.presetPosition"
          >
          </el-option>
        </el-select>
        <el-popover placement="bottom" width="260" v-model="showRenamePopover" trigger="manual">
          <div class="form-item" style="margin-bottom: 10px">
            <span class="form-item-label">预置位名称：</span>
            <el-input
              style="width: 134px"
              class="tree-type"
              v-model="setForm.presetName"
              v-specialChar
              maxlength="64"
              placeholder="请选择"
              size="mini"
            >
            </el-input>
          </div>
          <div style="text-align: right; margin: 0">
            <el-button
              size="mini"
              type="default"
              style="background-color: #c5c5c5 !important"
              @click="showRenamePopover = false"
              >取消</el-button
            >
            <el-button type="primary" size="mini" style="background-color: #1dd4e7 !important" @click="setPresetName"
              >确定</el-button
            >
          </div>
          <span class="rename" slot="reference" @click="rename">修改名称</span>
        </el-popover>
      </div> -->
      <!-- <div class="position-wrap" style="margin-bottom: 10px">
        <span>预置位：</span>
        <img :src="settingSrc" class="btns" @click="setPresetPosition()" />
        <img :src="delSrc" class="btns" @click="delPresetPosition()" />
        <img :src="arrowSrc" class="btns" @click="cameraCtrlRestSetPresetPos()" />
        <el-popover placement="bottom" width="260" v-model="showIsSettedPresetPositionPopover" trigger="manual">
          <div class="form-item" style="margin-bottom: 10px">
            <span class="form-item-label">关联预置位：</span>
            <el-select
              class="tree-type"
              v-model="setForm.isSettedPresetPosition"
              placeholder="请选择"
              size="mini"
              filterable
              clearable
            >
              <el-option
                v-for="(item, index) in isSettedPresetPositionList"
                :key="item.presetPosition + index"
                :label="item.presetName"
                :value="item.presetPosition"
              >
              </el-option>
            </el-select>
          </div>
          <div class="form-item" style="margin-bottom: 10px">
            <span class="form-item-label">设置守望时间：</span>
            <div style="display: inline">
              <el-input-number
                type="number"
                style="width: 100px"
                v-model="setForm.parkTime"
                placeholder="请选择"
                size="mini"
                :min="1"
                :max="9999"
                controls-position="right"
              />
              分钟
            </div>
          </div>
          <div style="text-align: right; margin: 0">
            <el-button
              size="mini"
              type="default"
              style="background-color: #c5c5c5 !important"
              @click="showIsSettedPresetPositionPopover = false"
              >取消</el-button
            >
            <el-button
              type="primary"
              size="mini"
              style="background-color: #1dd4e7 !important"
              @click="restPtzParkAction"
              >确定</el-button
            >
          </div>
          <img :src="partSrc" class="btns" slot="reference" @click="showRestPtzParkAction" />
        </el-popover>
      </div> -->
      <!-- <div class="position-wrap">
        <span>优先级：</span>
        <el-select v-model="priority" size="mini" @change="changePriority">
          <el-option v-for="item in priorityData" :label="item.label" :value="item.value" :key="item.key" />
        </el-select>
      </div> -->
    </div>
  </div>
</template>
<script>
  // import RobotControlDia from '../automation-inspection/pages/real/components/RobotControlDia'
  import debounce from 'lodash.debounce';
  import RobotControlDia from './RobotControlDia.vue';
  import NstdBoxTitle from './NstdBoxTitle.vue';
  import NstdVideoPlayer from './NstdVideoPlayerWfs.vue';
  import { VueCropper } from 'vue-cropper';
  import one from '../../../../assets/icon/one.png';
  import four from '../../../../assets/icon/four.png';
  import nine from '../../../../assets/icon/nine.png';
  import sixteen from '../../../../assets/icon/sixteen.png';
  import fullpage from '../../../../assets/icon/fullpage.png';
  import screenshot from '../../../../assets/icon/screenshot.png';
  import lbDo from '../../../../assets/icon/lb-do.png';
  import lb from '../../../../assets/icon/lb.png';
  import cew from '../../../../assets/icon/cew.png';
  import close from '../../../../assets/icon/close.png';
  import closeAll from '../../../../assets/icon/close-all.png';
  import kong from '@/assets/images/kong.png';
  import left from '@/assets/icon/left.png';
  import right from '@/assets/icon/right.png';
  import top from '../../../../assets/icon/top.png';
  import bottom from '@/assets/icon/bottom.png';
  import leftTop from '@/assets/icon/left-top.png';
  import rightTop from '@/assets/icon/right-top.png';
  import leftBottom from '@/assets/icon/left-bottom.png';
  import rightBottom from '@/assets/icon/right-bottom.png';
  import scanAdd from '@/assets/icon/scan-add.png';
  import copy from '@/assets/icon/copy.png';
  import add from '@/assets/icon/add.png';
  import sun from '@/assets/icon/sun.png';
  import set from '@/assets/icon/set.png';
  import scan from '@/assets/icon/scan.png';
  import copyYellow from '@/assets/icon/copy-yellow.png';
  import cutdown from '@/assets/icon/cutdown.png';
  import searchAdd from '@/assets/icon/search-add.png';
  import td from '@/assets/icon/3d.png';
  import voiceStop from '@/assets/icon/voice-stop.png';
  import voiceStart from '@/assets/icon/voice-start.png';
  import videoStart from '@/assets/icon/video-start.png';
  import videoStop from '@/assets/icon/video-stop.png';
  import setting from '@/assets/icon/setting.png';
  import del from '@/assets/icon/del.png';
  import arrow from '@/assets/icon/arrow.png';
  import part from '@/assets/icon/part.png';

  import {
    controlPtz,
    capturePicture,
    cameraCtrlRestRecstart,
    cameraCtrlRestRecstop,
    cameraCtrlRestRealPs3dLocation,
    camPresetPositionCfgDetail,
    cameraCtrlRestSetPresetPos,
    camPresetPositionCfgClear,
    camPresetPositionCfgSetCamPark,
    camPresetPositionCfgSet,
    cameraCtrlRestDownload,
    videoRealTimeDisplayInfo,
    realTimeStream,
    updVideoPriority,
    getStationBandwidth
  } from '@/api/inspect.js';
  import { getHwTemperature, StartVoice } from '@/api/inspect';
  export default {
    name: 'NstdVideoInspect',
    components: {
      NstdBoxTitle,
      NstdVideoPlayer,
      VueCropper,
      RobotControlDia
    },
    props: {
      currentDeviceInfo: {
        type: Object,
        default: () => {}
      },
      treeType: {
        type: String,
        default: ''
      }
    },
    data() {
      return {
        bandwidth: 0,
        priority: '',
        priorityData: [
          {
            label: 1,
            value: 1
          },
          {
            label: 2,
            value: 2
          },
          {
            label: 3,
            value: 3
          },
          {
            label: 4,
            value: 4
          },
          {
            label: 5,
            value: 5
          }
        ],
        videoListCopy: [],
        lbTime: '',
        lbIndex: 0,
        lbTimer: null,
        lbFlag: false,
        timerList: [],
        ip: window.location.hostname === 'localhost' ? process.env.VUE_APP_DEV_SERVER_IP : window.location.hostname,
        setShow: false,
        btnType: '',
        timer: null,
        lxTime: '',
        cropper: true,
        option: {
          img: kong
        },
        optList: [
          {
            controlCmd: '9',
            src: left,
            style: {
              width: '12px',
              height: '22px',
              top: 'calc( 50% - 11px )',
              left: '18px'
            }
          },
          {
            controlCmd: '10',
            src: right,
            style: {
              width: '12px',
              height: '22px',
              top: 'calc( 50% - 11px )',
              right: '18px'
            }
          },
          {
            controlCmd: '7',
            src: top,
            style: {
              width: '22px',
              height: '12px',
              top: '18px',
              left: 'calc( 50% - 11px )'
            }
          },
          {
            controlCmd: '8',
            src: bottom,
            style: {
              width: '22px',
              height: '12px',
              bottom: '18px',
              left: 'calc( 50% - 11px )'
            }
          },
          {
            controlCmd: '11',
            src: leftTop,
            style: {
              width: '12px',
              height: '12px',
              top: '28px',
              left: '28px'
            }
          },
          {
            controlCmd: '12',
            src: rightTop,
            style: {
              width: '12px',
              height: '12px',
              top: '28px',
              right: '28px'
            }
          },
          {
            controlCmd: '13',
            src: leftBottom,
            style: {
              width: '12px',
              height: '12px',
              bottom: '28px',
              left: '28px'
            }
          },
          {
            controlCmd: '14',
            src: rightBottom,
            style: {
              width: '12px',
              height: '12px',
              bottom: '28px',
              right: '28px'
            }
          }
        ],
        speed: 25,
        btnsList: [
          {
            controlCmd: '1',
            src: scanAdd,
            title: '焦距变大'
          },
          {
            controlCmd: '3',
            src: copy,
            title: '焦点前调'
          },
          {
            controlCmd: '5',
            src: add,
            title: '光圈扩大'
          },
          {
            controlCmd: '16',
            src: sun,
            title: '补光'
          },
          {
            controlCmd: '15',
            src: set,
            title: '雨刷'
          },
          {
            controlCmd: '2',
            src: scan,
            title: '焦距变小'
          },
          {
            controlCmd: '4',
            src: copyYellow,
            title: '焦点后调'
          },
          {
            controlCmd: '6',
            src: cutdown,
            title: '光圈缩小'
          }
          // {
          //   type: 'search-add',
          //   src: searchAdd,
          //   title: '电子放大'
          // },
          // {
          //   type: '3d',
          //   src: td,
          //   title: '3D放大'
          // }
        ],
        voiceFlag: true,
        videoFlag: true,
        presetPosition: '', // 当前预置点位
        positionList: [], // 预置位点位信息列表
        presetPositionConf: {}, // 当前预置点位配置信息
        isSettedPresetPositionList: [], // 当前关联的预置点位列表
        isSettedPresetPositionConf: {}, // 当前关联的预置点位配置信息
        settingSrc: setting,
        delSrc: del,
        arrowSrc: arrow,
        partSrc: part,
        setForm: {
          isSettedPresetPosition: '', // 当前关联的预置点位
          parkTime: '', // 设置守望时间
          isPark: false, // 守望位状态
          presetName: '' // 预置位名称
        },
        showIsSettedPresetPositionPopover: false, // 是否展示关联预置位弹框
        showRenamePopover: false, // 是否展示修改名称弹框
        // 速度调节配置
        speedMarks: {
          0: {
            style: {
              color: '#fff'
            },
            label: '0'
          },
          25: {
            style: {
              color: '#fff'
            },
            label: '25'
          },
          50: {
            style: {
              color: '#fff'
            },
            label: '50'
          },
          75: {
            style: {
              color: '#fff'
            },
            label: '75'
          },
          100: {
            style: {
              color: '#fff'
            },
            label: '100'
          }
        },
        scanFlag: false, // 开启滚轮放大缩小
        videoNum: 1, // 视频流分屏个数
        videoCol: 1, // 视频流分屏列数
        patrolDeviceCode: '', // 左侧树对应设备code
        nvrCode: '', // 当前视频流对应设备code
        stationCode: '', // 左侧树对应设备父级节点变电站code
        deviceIndex: 0, // 当前选中视频流下表
        curVideoConf: {}, // 当前选中视频流配置
        cropperFlag: false,
        videoList: [],
        ws1: null
      };
    },
    watch: {
      currentDeviceInfo: {
        async handler(n) {
          if (!n) {
            return;
          }
          if (this.$refs[`cropper${this.deviceIndex}`] && this.$refs[`cropper${this.deviceIndex}`].length) {
            this.$refs[`cropper${this.deviceIndex}`][0].clearCrop();
            this.$refs[`cropper${this.deviceIndex}`][0].stopCrop();
          }
          this.cropperFlag = false;
          console.log(this.deviceIndex, 'this.deviceIndex');
          console.log(this.videoList, 'this.videoList');
          this.videoList.splice(this.deviceIndex, 1, n);
          this.priority = n.priority || '';
          // if (!this.bandwidth) {
          //   const res = await getStationBandwidth(this.stationInfo.stationCode);
          //   this.bandwidth = res.data;
          // }
          const videoList = this.videoList.filter((item) => Object.keys(item).length);
          console.log(videoList, 'videoList');
          console.log(this.bandwidth, 'this.bandwidth');
          // if (videoList.length > this.bandwidth) {
          //   const videoLists = videoList.filter((item) => item.priority > this.priority);
          //   if (videoLists.length === 0) {
          //     this.closeVideoClient({ type: 'close' });
          //     return this.$message.warning('变电站带宽限制，请关闭其它摄像头');
          //   } else {
          //     const min = Math.max(...videoList.map((item) => item.priority));
          //     console.log(min, 'min');
          //     this.videoList.some((item, index) => {
          //       if (item.priority === min) {
          //         this.deviceIndex = index;
          //         this.closeVideoClient({ type: 'close' });
          //         return true;
          //       }
          //     });
          //   }
          // }

          this.curVideoConf = n;
          console.log('this.curVideoConf', this.curVideoConf);
          const { patrolDeviceCode, nvrCode, stationCode } = this.curVideoConf;
          this.patrolDeviceCode = patrolDeviceCode || '';
          this.nvrCode = nvrCode || '';
          this.stationCode = stationCode || '';
        },
        deep: true,
        immediate: true
      },
      presetPosition: {
        handler(n) {
          if (n) {
            const arr = this.positionList.filter((item) => item.presetPosition === n);
            if (arr.length) {
              this.presetPositionConf = arr[0] || {};
            }
          }
        },
        immediate: true
      },
      'setForm.isSettedPresetPosition': {
        handler(n) {
          if (n) {
            const arr = this.isSettedPresetPositionList.filter((item) => item.presetPosition === n);
            if (arr.length) {
              this.isSettedPresetPositionConf = arr[0] || {};
              this.setForm.isPark = this.isSettedPresetPositionConf?.isPark || false;
            }
          }
        },
        deep: true,
        immediate: true
      },
      patrolDeviceCode: {
        handler(n) {
          if (n) {
            this.presetPosition = '';
            this.setForm.isSettedPresetPosition = '';
            this.camPresetPositionCfgDetail();
            // 获取所有选中状态的预置点位
            this.camPresetPositionCfgDetail(1);
          }
        },
        deep: true,
        immediate: true
      }
    },
    computed: {
      videoStyle() {
        const item = this.videoCol;
        const itemBox = 100 / item + '%';
        return {
          'grid-template-columns': `repeat(${item}, ${itemBox})`,
          'grid-template-rows': `repeat(${item}, ${itemBox})`
        };
      },
      stationInfo() {
        return this.$store.state.station.stationInfo;
      },
      videoOptList() {
        //videoMode 视频类型(1 = 可见光, 2 = 红外, 3 = 可见光与红外)
        return [
          {
            type: 'opreat',
            src: one,
            name: '一屏',
            value: 'one'
          },
          {
            type: 'opreat',
            src: four,
            name: '四屏',
            value: 'four'
          },
          {
            type: 'opreat',
            src: nine,
            name: '九屏',
            value: 'nine'
          },
          {
            type: 'opreat',
            src: sixteen,
            name: '十六屏',
            value: 'sixteen'
          },
          {
            type: 'opreat',
            src: fullpage,
            name: '全屏',
            value: 'fullpage'
          },
          {
            type: 'devider'
          },
          {
            type: 'opreat',
            src: screenshot,
            name: '截图',
            value: 'screenshot'
          },
          {
            type: 'opreat',
            src: this.lbFlag ? lbDo : lb,
            name: '轮播',
            value: 'lunbo'
          },
          {
            type: 'devider'
          },
          {
            type: 'opreat',
            src: close,
            name: '关闭',
            value: 'close'
          },
          {
            type: 'opreat',
            src: closeAll,
            name: '关闭所有',
            value: 'close-all'
          }
        ];
      },
      voiceSrc() {
        return this.voiceFlag ? voiceStop : voiceStart;
      },
      videoSrc() {
        return this.videoFlag ? videoStart : videoStop;
      }
    },
    mounted() {
      window.addEventListener('mousewheel', this.mousewheel, false);
    },
    methods: {
      async changePriority() {
        if (!this.curVideoConf.nvrCode) return this.$message.error('请选择设备');
        await updVideoPriority(this.curVideoConf.patrolDeviceCode, this.priority);
      },
      handleClose() {
        this.setShow = !this.setShow;
      },
      // 语音对讲 -- 点击
      async voiceBtnClick() {
        if (!this.curVideoConf.nvrCode) return this.$message.error('请选择设备');
        this.voiceFlag = !this.voiceFlag;
        var ws = null; //实现WebSocket
        // var record = null; //多媒体对象，用来处理音频
        var flag = false;

        var player = new PCMPlayer({
          encoding: '16bitInt',
          channels: 1,
          sampleRate: 8000,
          flushingTime: 1000
        });
        const init = (rec) => {
          this.record = rec;
        };
        //录音对象
        var Recorder = function (stream) {
          var sampleBits = 16; //输出采样数位 8, 16
          var sampleRate = 8000; //输出采样率
          var context = new AudioContext();
          var audioInput = context.createMediaStreamSource(stream);
          var recorder = context.createScriptProcessor(4096, 1, 1);
          var audioData = {
            size: 0, //录音文件长度
            buffer: [], //录音缓存
            inputSampleRate: 48000, //输入采样率
            inputSampleBits: 16, //输入采样数位 8, 16
            outputSampleRate: sampleRate, //输出采样数位
            oututSampleBits: sampleBits, //输出采样率
            clear: function () {
              this.buffer = [];
              this.size = 0;
            },
            input: function (data) {
              this.buffer.push(new Float32Array(data));
              this.size += data.length;
            },
            compress: function () {
              //合并压缩
              //合并
              var data = new Float32Array(this.size);
              var offset = 0;
              for (var i = 0; i < this.buffer.length; i++) {
                data.set(this.buffer[i], offset);
                offset += this.buffer[i].length;
              }
              //压缩
              var compression = parseInt(this.inputSampleRate / this.outputSampleRate);
              var length = data.length / compression;
              var result = new Float32Array(length);
              var index = 0,
                j = 0;
              while (index < length) {
                result[index] = data[j];
                j += compression;
                index++;
              }
              return result;
            },
            encodePCM: function () {
              //这里不对采集到的数据进行其他格式处理，如有需要均交给服务器端处理。
              var sampleRate = Math.min(this.inputSampleRate, this.outputSampleRate);
              var sampleBits = Math.min(this.inputSampleBits, this.oututSampleBits);
              var bytes = this.compress();
              var dataLength = bytes.length * (sampleBits / 8);
              var buffer = new ArrayBuffer(dataLength);
              var data = new DataView(buffer);
              var offset = 0;
              for (var i = 0; i < bytes.length; i++, offset += 2) {
                var s = Math.max(-1, Math.min(1, bytes[i]));
                data.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);
              }
              return new Blob([data]);
            }
          };

          var sendData = function () {
            //对以获取的数据进行处理(分包)
            var reader = new FileReader();
            reader.onload = (e) => {
              var outbuffer = e.target.result;
              var arr = new Int8Array(outbuffer);
              if (arr.length > 0) {
                var tmparr = new Int8Array(1024);
                var j = 0;
                for (var i = 0; i < arr.byteLength; i++) {
                  tmparr[j++] = arr[i];
                  if ((i + 1) % 1024 == 0) {
                    ws.send(tmparr);
                    if (arr.byteLength - i - 1 >= 1024) {
                      tmparr = new Int8Array(1024);
                    } else {
                      tmparr = new Int8Array(arr.byteLength - i - 1);
                    }
                    j = 0;
                  }
                  if (i + 1 == arr.byteLength && (i + 1) % 1024 != 0) {
                    ws.send(tmparr);
                  }
                }
              }
            };
            reader.readAsArrayBuffer(audioData.encodePCM());
            audioData.clear(); //每次发送完成则清理掉旧数据
          };

          this.start = function () {
            audioInput.connect(recorder);
            recorder.connect(context.destination);
          };

          this.stop = function () {
            recorder.disconnect();
          };

          this.getBlob = function () {
            return audioData.encodePCM();
          };

          this.clear = function () {
            audioData.clear();
          };

          recorder.onaudioprocess = function (e) {
            var inputBuffer = e.inputBuffer.getChannelData(0);
            audioData.input(inputBuffer);
            sendData();
          };
        };
        /*
         * WebSocket
         */
        const useWebSocket = () => {
          console.info('999999');
          ws = new WebSocket(`${window.location.protocol === 'http:' ? 'ws' : 'wss'}://${this.ip}/voiceIntercomWs/`);
          ws.binaryType = 'arraybuffer'; //传输的是 ArrayBuffer 类型的数据
          ws.onopen = () => {
            console.log('握手成功');
            flag = true;
            if (ws.readyState == 1) {
              //ws进入连接状态，则每隔500毫秒发送一包数据
              this.record.start();
            }
          };

          ws.onmessage = function (msg) {
            // console.info(msg)
          };

          ws.onerror = function (err) {
            // console.info(err)
          };

          ws.addEventListener('message', function (event) {
            var data = new Uint8Array(event.data);
            player.feed(data);
          });
        };
        const curVideoConf = this.curVideoConf;
        const useWebSocket1 = () => {
          console.info('55555');
          const socketURL = `${window.location.protocol === 'http:' ? 'ws' : 'wss'}://${this.ip}/voiceStreamWs/`;
          this.ws1 = new WebSocket(socketURL);
          this.ws1.binaryType = 'arraybuffer'; //传输的是 ArrayBuffer 类型的数据
          this.ws1.onopen = () => {
            console.log('握手成功');
            this.ws1.send(JSON.stringify({ t: 'talkOpen', c: curVideoConf.nvrCode }));
          };
          if (!this.ws1) return false;
          const timer = setInterval(() => {
            const json = JSON.stringify({ t: 'talkOpen', c: curVideoConf.nvrCode });
            this.ws1.send(json);
          }, 5000);
          this.timerList.push(timer);
          this.ws1.onmessage = function (msg) {};

          this.ws1.onerror = function (err) {
            // console.info(err)
          };
        };
        if (!this.voiceFlag) {
          const data = {
            id: this.curVideoConf.nvrCode,
            channelNo: this.curVideoConf.nvrChannel
          };
          const res = await StartVoice(data);
          if (Number(res.code) !== 200) return false;
          navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
          console.log(navigator.getUserMedia, 'navigator.getUserMedia');
          if (!navigator.getUserMedia) {
            alert('浏览器不支持音频输入');
          } else {
            navigator.getUserMedia(
              {
                audio: true
              },
              function (mediaStream) {
                init(new Recorder(mediaStream));
                console.log('开始对讲');
                useWebSocket();
                useWebSocket1();
              },
              function (error) {
                console.log(error);
                switch (error.message || error.name) {
                  case 'PERMISSION_DENIED':
                  case 'PermissionDeniedError':
                    console.info('用户拒绝提供信息。');
                    break;
                  case 'NOT_SUPPORTED_ERROR':
                  case 'NotSupportedError':
                    console.info('浏览器不支持硬件设备。');
                    break;
                  case 'MANDATORY_UNSATISFIED_ERROR':
                  case 'MandatoryUnsatisfiedError':
                    console.info('无法发现指定的硬件设备。');
                    break;
                  default:
                    console.info('无法打开麦克风。异常信息:' + (error.code || error.name));
                    break;
                }
              }
            );
          }
        } else {
          this.record.stop();
          this.record.clear();
          this.ws1.send(JSON.stringify({ t: 'talkClose', c: curVideoConf.nvrCode }));
        }
      },
      // 修改名称
      rename() {
        if (!this.nvrCode) {
          this.$message.error('请选择设备！');
          return;
        }
        if (!this.presetPosition) {
          this.$message.error('请选择预置位！');
          return;
        }
        this.showRenamePopover = true;
      },
      // 修改预置位名称
      setPresetName() {
        if (!this.setForm.presetName) {
          this.$message.error('预置位名称不能为空！');
          return;
        }
        this.presetPositionFun(this.setForm.presetName);
      },
      // 设置守望位 -- 图标点击
      async showRestPtzParkAction() {
        if (!this.nvrCode) {
          this.$message.error('请选择设备！');
          return;
        }
        this.showIsSettedPresetPositionPopover = true;
      },
      // 设置守望位
      async restPtzParkAction() {
        if (!this.setForm.isSettedPresetPosition) {
          this.$message.error('请选择关联预置位！');
          return;
        }
        const { nvrCode, nvrChannel, stationCode, patrolDeviceCode } = this.curVideoConf;
        const { presetPosition, id: presetPositionId } = this.isSettedPresetPositionConf;
        const { isPark, parkTime } = this.setForm;
        const regex = /^[1-9]\d*$/;
        if (!regex.test(parkTime)) {
          this.$message.error('请输入正确的守望时间！');
          return;
        }
        const params = {
          id: presetPositionId,
          stationCode: stationCode,
          patroldeviceCode: patrolDeviceCode,
          parentCode: nvrCode,
          channelId: String(nvrChannel),
          presetPosition: presetPosition,
          isPark: 1,
          parkTime: parkTime * 60
        };
        const { code, data } = await camPresetPositionCfgSetCamPark(params);
        if (code !== 200 || !data) {
          this.$message.error('操作失败！');
          return;
        }
        this.$message.success('操作成功！');
        this.showIsSettedPresetPositionPopover = false;
      },
      // 设置预置位 -- 点击
      async setPresetPosition() {
        if (!this.nvrCode) {
          this.$message.error('请选择设备！');
          return;
        }
        if (!this.presetPosition) {
          this.$message.error('请选择预置位！');
          return;
        }
        this.presetPositionFun();
      },
      // 设置预置点位
      async presetPositionFun(newPresetName) {
        const { nvrCode, nvrChannel, stationCode, patrolDeviceCode } = this.curVideoConf;
        const { presetName, presetPosition, id: presetPositionId } = this.presetPositionConf;
        const params = {
          id: presetPositionId,
          stationCode: this.stationCode,
          patroldeviceCode: patrolDeviceCode,
          parentCode: nvrCode,
          channelId: String(nvrChannel),
          presetPosition: presetPosition,
          presetName: newPresetName || presetName
        };
        const { code, data } = await camPresetPositionCfgSet(params);
        if (code !== 200 || !data) {
          this.$message.error('操作失败！');
          return;
        }
        this.setForm.presetName = '';
        this.$message.success('操作成功！');
        this.presetPositionConf.isSetted = 1;
        this.camPresetPositionCfgDetail();
        this.camPresetPositionCfgDetail(1);
        // 如果是修改预置位名称，则操作成功后需要关闭对应popover
        if (this.showRenamePopover) {
          this.showRenamePopover = false;
        }
      },
      // 删除预置位
      async delPresetPosition() {
        if (!this.nvrCode) {
          this.$message.error('请选择设备！');
          return;
        }
        if (!this.presetPosition) {
          this.$message.error('请选择预置位！');
          return;
        }

        const { nvrCode, nvrChannel, patrolDeviceCode } = this.curVideoConf;
        const { presetPosition, id: presetPositionId } = this.presetPositionConf;
        const params = {
          patroldeviceCode: patrolDeviceCode,
          id: presetPositionId,
          channelId: String(nvrChannel),
          presetPosition: presetPosition,
          parentCode: nvrCode
        };
        const { code, data } = await camPresetPositionCfgClear(params);
        if (code !== 200 || !data) {
          this.$message.error('操作失败！');
          return;
        }
        this.presetPositionConf.isSetted = 0;
        this.$message.success('操作成功！');
        this.camPresetPositionCfgDetail();
        this.camPresetPositionCfgDetail(1);
      },
      // 转到预置位
      async cameraCtrlRestSetPresetPos() {
        if (!this.nvrCode) {
          this.$message.error('请选择设备！');
          return;
        }
        if (!this.presetPosition) {
          this.$message.error('请选择预置位！');
          return;
        }

        const { nvrCode, nvrChannel, patrolDeviceCode } = this.curVideoConf;
        const { presetPosition, isSetted } = this.presetPositionConf;
        const params = {
          patroldeviceCode: patrolDeviceCode,
          id: nvrCode,
          channelNo: String(nvrChannel),
          presetIndex: presetPosition,
          presetCmd: '3',
          presetName: ''
        };

        if (isSetted === 0) {
          return this.$alert('当前预置位尚未设置');
        }
        const { code, data } = await cameraCtrlRestSetPresetPos(params);
        if (code !== 200 || !data) {
          this.$message.error('操作失败！');
          return;
        }
        this.$message.success('操作成功！');
      },
      // 获取预置位列表信息
      async camPresetPositionCfgDetail(isSetted) {
        const { patrolDeviceCode, stationCode } = this.curVideoConf;
        const params = {
          patroldeviceCode: patrolDeviceCode,
          stationCode: stationCode
        };
        if (isSetted === 1) {
          params.isSetted = isSetted;
        }
        const { code, data } = await camPresetPositionCfgDetail(params);
        if (code !== 200 || !data) {
          this.$message.error('操作失败！');
          return;
        }
        if (isSetted === 1) {
          this.isSettedPresetPositionList = data || [];
          const item = data.filter((item) => item.isPark === 1);
          // this.setForm.isSettedPresetPosition = item && item[0].presetPosition
          this.setForm.isSettedPresetPosition = item?.[0]?.presetPosition ?? '';
        } else {
          this.positionList = data || [];
        }
      },
      // 3d放大
      cameraCtrlRestRealPs3dLocation: debounce(async function () {
        if (!this.cropperFlag) {
          return;
        }
        if (!this.$refs[`cropper${this.deviceIndex}`]) {
          return;
        }
        const { x1, x2, y1, y2 } = this.$refs[`cropper${this.deviceIndex}`][0].getCropAxis();
        const pW = 1125; // 当前视频流最外层容器宽度
        const margin = 5; // 间距
        let tW; // 默认宽度
        let tH; // 默认高度
        // (tH / tW) 视频流容器对应宽高比
        let cropperW;
        let cropperH;
        if (this.btnType === '3d') {
          tW = 1920;
          tH = 1080;
          cropperW = (pW - margin * this.videoCol) / this.videoCol;
          cropperH = ((pW - margin * this.videoCol) / this.videoCol) * (tH / tW);
          const xTop = Math.ceil((x1 * 255) / cropperW);
          const yTop = Math.ceil((y1 * 255) / cropperH);
          const xBottom = Math.ceil((x2 * 255) / cropperW);
          const yBottom = Math.ceil((y2 * 255) / cropperH);
          const { nvrChannel, nvrCode, patrolDeviceCode } = this.curVideoConf;
          const params = {
            patroldeviceCode: patrolDeviceCode,
            id: nvrCode,
            key: String(nvrChannel),
            xTop: xTop,
            yTop: yTop,
            xBottom: xBottom,
            yBottom: yBottom
          };
          const { code, data } = await cameraCtrlRestRealPs3dLocation(params);
          if (code !== 200 || !data) {
            this.$message.error('操作失败！');
            return;
          }
        } else {
          const videoStyle = this.$refs.videoList.getBoundingClientRect();
          console.log(videoStyle, 'videoStyle');
          const rateX = 1000 / (788 / this.videoCol);
          const rateY = 1000 / (videoStyle.height / this.videoCol);
          const width = (videoStyle.width - 788) / this.videoCol / 2;
          const data = {
            patrolDeviceCode: this.curVideoConf.patrolDeviceCode,
            position1: `${Math.ceil((x1 - width) * rateX)},${Math.ceil((videoStyle.height / this.videoCol - y2) * rateY)}`,
            position2: `${Math.ceil((x1 - width) * rateX)},${Math.ceil((videoStyle.height / this.videoCol - y1) * rateY)}`,
            position3: `${Math.ceil((x2 - width) * rateX)},${Math.ceil((videoStyle.height / this.videoCol - y1) * rateY)}`,
            position4: `${Math.ceil((x2 - width) * rateX)},${Math.ceil((videoStyle.height / this.videoCol - y2) * rateY)}`,
            channelNo: '2'
          };
          const res = await getHwTemperature(data);
        }
      }, 1000),
      videoPlayerClick(index) {
        // debugger;
        this.curVideoConf = this.videoList[index] || {};
        const { patrolDeviceCode, nvrCode, stationCode } = this.curVideoConf;
        this.patrolDeviceCode = patrolDeviceCode || '';
        this.nvrCode = nvrCode || '';
        this.stationCode = stationCode || '';
        this.deviceIndex = index;
        this.$emit('setCheckedIndex', index);
      },
      // 云镜控制 -- 点击
      controlClick(item, type) {
        if (!this.nvrCode && type === 'down') {
          this.$message.error('请选择设备！');
          return;
        }
        if (!this.nvrCode && type === 'up') {
          return;
        }
        if (item.controlCmd) {
          this.controlPtz(item.controlCmd, type);
        } else if (item.type === '3d' && type === 'down') {
          this.btnType = '3d';
          this.$nextTick(() => {
            this.cropperFlag = !this.cropperFlag;
            this.$refs[`cropper${this.deviceIndex}`][0].clearCrop();
            if (this.cropperFlag) {
              this.$refs[`cropper${this.deviceIndex}`][0].startCrop();
            } else {
              this.$refs[`cropper${this.deviceIndex}`][0].stopCrop();
            }
          });
        } else if (item.type === 'search-add') {
          if (type === 'down') {
            this.scanFlag = !this.scanFlag;
          }
        }
      },
      // 通过鼠标滚轮进行放大缩小
      mousewheel: debounce(function (e) {
        if (!this.scanFlag) {
          return;
        }
        const controlCmd = e.deltaY > 0 ? '1' : '2';
        this.controlPtz(controlCmd, 'stop');
      }, 50),
      // 云镜控制
      async controlPtz(controlCmd, type) {
        const obj = {
          up: 1,
          down: 0
        };
        const { nvrChannel, nvrCode, patrolDeviceCode } = this.curVideoConf;
        console.log(this.curVideoConf, 'this.curVideoConf');
        const params = {
          patroldeviceCode: patrolDeviceCode,
          controlCmd: controlCmd,
          id: nvrCode,
          channelNo: String(nvrChannel),
          isStop: obj[type] || 0,
          speed: Math.ceil((this.speed / 100) * 7) || 1
        };
        const { code, data } = await controlPtz(params);
        if (code !== 200 || !data) {
          this.$message.error('操作失败！');
          return;
        }
        // 鼠标滚轮进行放大缩小接口调用成功后立即停止操作
        if (type === 'stop') {
          setTimeout(() => {
            this.controlPtz(controlCmd, 'up');
          }, 500);
        }
      },
      // 录像 -- 点击
      async videoBtnClick() {
        if (!this.nvrCode) {
          this.$message.error('请选择设备！');
          return;
        }
        if (!this.lxTime) return this.$message.error('请输入录像时长');
        const { nvrChannel, nvrCode, patrolDeviceCode } = this.curVideoConf;
        const params = {
          patroldeviceCode: patrolDeviceCode,
          id: nvrCode,
          channelNo: nvrChannel
        };
        const obj = {
          true: cameraCtrlRestRecstart, // 开始录像
          false: cameraCtrlRestRecstop // 结束录像
        };
        if (this.videoFlag) {
          this.timer = setTimeout(
            async () => {
              const res = await cameraCtrlRestRecstop(params);
              if (res.code === 200) {
                this.videoFlag = true;
                const { resultData } = res.data;
                this.cameraCtrlRestDownload(resultData);
              }
            },
            this.lxTime * 60 * 1000
          );
        }
        const { code, data } = await obj[this.videoFlag](params);
        if (code !== 200 || !data) {
          this.$message.error('操作失败！');
          this.videoFlag = true;
          return;
        }
        if (!this.videoFlag) {
          if (this.timer) clearTimeout(this.timer);
          const { resultData } = data;
          this.cameraCtrlRestDownload(resultData);
        }
        this.videoFlag = !this.videoFlag;
      },
      // 录像下载
      async cameraCtrlRestDownload(item) {
        if (!item || !item.recodePath) {
          return;
        }
        const params = {
          filePath: item.recodePath
        };
        const axiosConfig = {
          responseType: 'blob'
        };
        cameraCtrlRestDownload(params, axiosConfig).then((res) => {
          const URL = window.URL || window.webkitURL;
          const url = URL.createObjectURL(res.data);
          let link = document.createElement('a');
          link.style.display = 'none';
          link.href = url;
          let name = '录像文件';
          const fileName = res.headers['content-disposition'];
          if (fileName) {
            name = /filename="(.*)?";/.exec(fileName)?.[1] ?? '录像文件';
          }
          link.setAttribute('download', name);
          document.body.appendChild(link);
          link.click();
        });
      },
      clearLb() {
        this.lbFlag = false;
        if (this.lbTimer) {
          clearInterval(this.lbTimer);
          this.lbTimer = null;
          const videoList = this.videoListCopy;
          videoList.map(async (item) => {
            if (Object.keys(item).length) {
              const params = {
                patrolDeviceCodes: item.id,
                stationCode: item.stationCode
              };
              const res1 = await videoRealTimeDisplayInfo(params);
              const obj = res1.data[0];
              const params1 = {
                channelNos: obj?.nvrChannel || '',
                code: '',
                id: obj?.nvrCode || '',
                psUrl: ''
              };
              await realTimeStream(params1);
              this.videoList = videoList;
            }
          });
        }
      },
      // 视频流底部操作按钮 -- 点击
      async videoOptClick(item) {
        if (item.value === 'cewen') {
          this.btnType = 'cewen';
          this.$nextTick(() => {
            this.cropperFlag = !this.cropperFlag;
            this.$refs[`cropper${this.deviceIndex}`][0].clearCrop();
            if (this.cropperFlag) {
              this.$refs[`cropper${this.deviceIndex}`][0].startCrop();
            } else {
              this.$refs[`cropper${this.deviceIndex}`][0].stopCrop();
            }
          });
        }
        if (item.value === 'lunbo') {
          if (!this.lbTime) return this.$message.warning('请输入轮播间隔！');
          this.lbFlag = !this.lbFlag;
          if (this.lbFlag) {
            this.videoListCopy = this.videoList;
            // .filter(item => Object.keys(item).length !== 0)
            const videoList = JSON.parse(JSON.stringify(this.videoList));
            this.videoListCopy = videoList;
            if (this.videoList.length <= this.videoNum) return false;
            this.lbIndex = 1;
            const videoList1 = videoList.slice(
              this.lbIndex * this.videoNum,
              this.lbIndex * this.videoNum + this.videoNum
            );
            videoList1.map(async (item) => {
              if (Object.keys(item).length) {
                const params = {
                  patrolDeviceCodes: item.id,
                  stationCode: item.stationCode
                };
                const res1 = await videoRealTimeDisplayInfo(params);
                const obj = res1.data[0];
                const params1 = {
                  channelNos: obj?.nvrChannel || '',
                  code: '',
                  id: obj?.nvrCode || '',
                  psUrl: ''
                };
                await realTimeStream(params1);
                this.videoList = videoList1;
              }
            });
            this.lbTimer = setInterval(() => {
              this.lbIndex++;
              if (this.lbIndex * this.videoNum >= videoList.length) this.lbIndex = 0;
              const videoList1 = videoList.slice(
                this.lbIndex * this.videoNum,
                this.lbIndex * this.videoNum + this.videoNum
              );
              videoList1.map(async (item) => {
                if (Object.keys(item).length) {
                  const params = {
                    patrolDeviceCodes: item.id,
                    stationCode: item.stationCode
                  };
                  const res1 = await videoRealTimeDisplayInfo(params);
                  const obj = res1.data[0];
                  const params1 = {
                    channelNos: obj?.nvrChannel || '',
                    code: '',
                    id: obj?.nvrCode || '',
                    psUrl: ''
                  };
                  await realTimeStream(params1);
                  this.videoList = videoList1;
                }
              });
            }, this.lbTime * 1000);
          } else {
            this.clearLb();
          }
        }
        const obj = {
          one: 1,
          four: 4,
          nine: 9,
          sixteen: 16
        };
        if (item.type === 'opreat') {
          if (obj[item.value]) {
            this.clearLb();
            this.videoNum = obj[item.value];
            this.videoCol = Math.sqrt(obj[item.value]);
            const total = this.videoNum - this.videoList.length;
            if (total > 0) {
              for (let i = 1; i <= total; i++) {
                this.videoList = [...this.videoList, {}];
              }
              this.$emit('getVideoList', this.videoList);
            }
          }
        }
        if (item.value === 'screenshot') {
          this.capturePicture();
        }
        if (item.value === 'fullpage') {
          this.clearLb();
          if (!this.videoList[this.deviceIndex].guid) return false;
          const elment = this.$refs.videoList?.children?.[this.deviceIndex] ?? null;
          if (elment) {
            this.toggleFullscreen(elment);
          }
        }
        if (['close', 'close-all'].includes(item.value)) {
          this.clearLb();
          this.nvrCode = '';
          if (item.value === 'close' && this.deviceIndex < 0) {
            this.$message.error('请选择需要关闭的设备！');
            return;
          }
          this.$confirm('确定要关闭吗?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          })
            .then(() => {
              this.closeVideoClient({ type: item.value, index: this.deviceIndex });
            })
            .catch(() => {
              this.$message.info('已取消!');
            });
        }
      },
      toggleFullscreen(el) {
        if (!document.fullscreenElement) {
          el.requestFullscreen().catch((err) => {
            console.log(`打开全屏模式失败: ${err.message} (${err.name})`);
          });
        } else {
          this.exitFullscreen();
        }
      },
      exitFullscreen() {
        if (document.exitFullscreen) {
          document.exitFullscreen();
        }
      },
      // 关闭当前视频流或者所有窗口
      closeVideoClient(item) {
        const { type, index } = item;
        if (type === 'close') {
          this.videoList[this.deviceIndex] = {};
        } else if (type === 'close-all') {
          this.videoList = this.videoList.map((item) => {
            item = {};
            return item;
          });
        }
        this.$emit('getVideoList', this.videoList);
        // this.$message.success('操作成功！')
        this.$forceUpdate();
      },
      // 截图
      async capturePicture() {
        if (!this.nvrCode) {
          this.$message.error('请选择设备！');
          return;
        }
        const { nvrChannel, nvrCode } = this.curVideoConf;
        const params = {
          id: nvrCode,
          channelNo: nvrChannel,
          method: 2
        };
        const { code, data } = await capturePicture(params);
        if (code !== 200 || !data) {
          this.$message.error('操作失败！');
          return;
        }
        const { resultData } = data;
        if (resultData.imageStream) {
          const img64 = resultData.imageStream;
          const imgHref = img64.replace('base64,', 'data:image/jpeg;base64,');
          let a = document.createElement('a');
          a.setAttribute('href', imgHref);
          a.setAttribute('download', nvrCode + '.jpg');
          a.setAttribute('target', '_blank');
          const clickEvent = document.createEvent('MouseEvents');
          clickEvent.initEvent('click', true, true);
          a.dispatchEvent(clickEvent);
        }
      }
    },
    beforeDestroy() {
      if (this.lbTimer) clearInterval(this.lbTimer);
      if (this.time) clearInterval(this.time);
      this.timerList.map((item) => {
        if (item) clearInterval(item);
      });
    }
  };
</script>
<style lang="less">
  .real-robot.mb-dialog {
    position: static;
    width: 330px;
    .el-scrollbar {
      height: 78vh !important;
    }
  }
</style>
<style lang="less" scoped>
  .container {
    display: flex;
  }
  .video-wrap {
    // width: 1120px;
    flex: 1;
    margin-right: 10px;
  }
  .video {
    // width: 1120px;
    width: 100%;
    height: 630px;
    // display: flex;
    // flex-wrap: wrap;
    // justify-content: space-around;
    // align-items: flex-start;
    display: grid;
    .player-wrap {
      position: relative;
      position: relative;
      background-color: #000;
      margin-left: 1px;
      margin-top: 1px;
      .mark {
        position: absolute;
        pointer-events: none;
        top: 0px;
        left: 0px;
        right: 0px;
        bottom: 0px;
        z-index: 1;
      }

      .active {
        top: -1px;
        left: -1px;
        right: -1px;
        bottom: -1px;
        border: 1px dashed red;
      }
    }
  }
  .video-1 {
    width: 1120px;
    height: 630px;
    background-color: #000;
  }
  .video-2 {
    width: 560px;
    height: 315px;
    background-color: #000;
  }
  .video-3 {
    width: 1120px;
    height: 630px;
    background-color: #000;
  }
  .video-4 {
    width: 1120px;
    height: 630px;
    background-color: #000;
  }
  .video-opt {
    display: flex;
    align-items: center;
    justify-content: center;
    // width: 1120px;
    width: 100%;
    height: 90px;
    margin-top: 10px;
    // background: linear-gradient(271deg, rgba(29, 212, 231, 0) 0%, #1dd4e7 60%, rgba(29, 212, 231, 0) 100%);
    border-radius: 4px;
    border: 1px solid;
    border-image: linear-gradient(270deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0)) 1 1;
    .opreat {
      width: 50px;
      display: flex;
      flex-direction: column;
      align-items: center;
      margin-right: 50px;
      cursor: pointer;
      img {
        width: 28px;
        height: 28px;
        margin-bottom: 4px;
      }
      span {
        display: inline-block;
        font-family:
          PingFangSC,
          PingFang SC;
        font-weight: 500;
        font-size: 12px;
        color: #ffffff;
        line-height: 20px;
        text-align: center;
        font-style: normal;
      }
    }
    .devider {
      width: 1px;
      height: 60px;
      margin-right: 50px;
      background: linear-gradient(180deg, rgba(225, 247, 255, 0) 0%, #d1f2ff 48%, rgba(192, 236, 255, 0) 100%);
    }
  }
  .opt-wrap {
    width: 330px;
    height: 730px;
    margin-right: 10px;
    .dial-wrap {
      display: flex;
      height: 120px;
      .opt-left {
        width: 120px;
        height: 120px;
        border-radius: 60px;
        margin-right: 10px;
        background-image: url('~@/assets/icon/opt-bg.png');
        background-repeat: no-repeat;
        background-size: 100% 100%;
        position: relative;
        cursor: pointer;
        img {
          position: absolute;
        }
        .center-icon {
          position: absolute;
          width: 32px;
          height: 32px;
          bottom: calc(50% - 16px);
          right: calc(50% - 16px);
          background: #1dd4e7;
          border-radius: 16px;
        }
      }
      .opt-right {
        flex: 1;
        display: flex;
        flex-direction: column;
        justify-content: center;
        .txt {
          font-family:
            PingFangSC,
            PingFang SC;
          font-weight: 500;
          font-size: 12px;
          color: #ffffff;
          line-height: 17px;
          text-align: left;
          font-style: normal;
        }
        .speed {
          margin-left: 4px;
          margin-right: 10px;
          margin-top: 20px;
        }
      }
    }
    .opt-btns {
      width: 300px;
      display: flex;
      flex-wrap: wrap;
      margin-top: 20px;
      .btns {
        width: 24px;
        height: 24px;
        margin-left: 34px;
        margin-bottom: 15px;
        cursor: pointer;
      }
    }
    .voice-video {
      display: flex;
      align-items: center;
      margin-left: 34px;
      margin-bottom: 10px;
      cursor: pointer;
      .box {
        display: flex;
        align-items: center;
        margin-right: 20px;
        img {
          width: 26px;
          height: 26px;
          margin-right: 4px;
        }
        .txt {
          width: 48px;
          height: 17px;
          font-family:
            PingFangSC,
            PingFang SC;
          font-weight: 500;
          font-size: 12px;
          color: #ffffff;
          line-height: 17px;
          text-align: left;
          font-style: normal;
        }
      }
    }
    .position-wrap {
      margin-left: 34px;
      margin-bottom: 10px;
      display: flex;
      align-items: center;
      span {
        width: 64px;
        height: 17px;
        font-family:
          PingFangSC,
          PingFang SC;
        font-weight: 500;
        font-size: 12px;
        color: #ffffff;
        line-height: 17px;
        text-align: left;
        font-style: normal;
        display: flex;
      }
      img {
        width: 20px;
        height: 18px;
        margin-left: 10px;
        cursor: pointer;
      }
    }
  }
  .rename {
    margin-left: 10px;
    text-decoration: underline;
    cursor: pointer;
  }
  .form-item-label {
    display: inline-block;
    width: 100px;
    color: #fff;
    font-family:
      PingFangSC,
      PingFang SC;
    font-weight: 400;
    font-size: 14px;
    line-height: 20px;
    text-align: center;
    font-style: normal;
  }
  .cropper-mark {
    width: 100%;
    height: 100%;
    background-image: none !important;
    /deep/.cropper-move {
      cursor: inherit !important;
    }
    /deep/.vue-cropper {
      background-image: none !important;
    }
    /deep/.cropper-box-canvas img {
      display: none !important;
    }
    /deep/.cropper-view-box {
      img {
        display: none !important;
      }
    }
  }
  /deep/.el-select__wrapper.is-filterable {
    width: 140px !important;
    height: 30px !important;
  }
  /deep/ .el-select__wrapper {
    width: 140px !important;
    height: 30px !important;
    background-color: transparent !important;
  }
  .speed /deep/ .el-slider__button {
    border-color: #1dd4e7; /* 滑块按钮的边框颜色 */
  }

  .speed /deep/ .el-slider__bar {
    background-color: #1dd4e7; /* 滑块条的背景颜色 */
  }
</style>
